/*********************************************************************
* File: World.cpp
*
* \brief Implements the world information manager.
*
* \author Instituto Superior Tecnico de Lisboa, Portugal
* \author Technical University of Lisbon, Portugal
* 
* \author Agentes Autonomos e Sistemas Multiagente
* \author Autonomous Agents and Multiagent Systems
* 
* \version	1.0
* \date		2006/2007
*********************************************************************/
#include "World.h"
#include "Tournament.h"
using namespace game;
#include "../agents/Agent.h"
using namespace agents;

/**
* \brief The class constructor.
**/
World::World()
{
	_isMapInitialized = false;
	mapType = MapTypes::unknown;
	isVersion16 = false;
	hostEdict = NULL;

	newRound();
}

/**
* \brief The class destructor.
**/
World::~World(){}

/**
* \brief Setups a new round.
*
* Should be called only ONCE per round.
**/
void World::newRound()	
{
	if (!isRoundOver() && isVersion16)
		return; 

	_timeBombWasPlanted = -1;
	_isBombPlanted = false;
	_isRoundOver = false;
	_timeRoundStarted = gpGlobals->time;

	if(g_tournament.isOn())
		g_tournament.newRound();

	for(int i=0; i<gpGlobals->maxClients; i++)
	{
		if (g_world->agents[i])
			g_world->agents[i]->newRound();
		g_radioSelect[i] = 0;
	}

	// Clear Array of Player Stats
	for(int i=0; i<gpGlobals->maxClients; i++)
	{
		g_threatTab[i].soundPosition = g_vecZero;
		g_threatTab[i].hearingDistance = 0.0;
		g_threatTab[i].timeSoundLasting = 0.0;
	}
}
/** 
* \brief Gets the map type.
*
* \see game::IWorld::getMapType
**/
MapTypes::Enumeration World::getMapType()
{ 
	if((mapType & MapTypes::assassination) != 0)
		return MapTypes::assassination;
	else if((mapType & MapTypes::bombDefuse) != 0)
		return MapTypes::bombDefuse;
	else if((mapType & MapTypes::hostageRescue) != 0)
		return MapTypes::hostageRescue;
	else
		return MapTypes::unknown;
}
/** 
* \brief Gets the map name.
*
* \see game::IWorld::getMapName
**/
void World::getMapName(char buffer[MAP_NAME_MAX_SIZE])
{
	strcpy(buffer, STRING(gpGlobals->mapname));
}
/** 
* \brief Gets the time the round ends.
*
* \see game::IWorld::getTimeRoundEnds
**/
float World::getTimeRoundEnds()
{
	float timeRoundEnds = min(CVAR_GET_FLOAT("mp_roundtime"),9);
	timeRoundEnds *= 60;
	timeRoundEnds += CVAR_GET_FLOAT("mp_freezetime");
	timeRoundEnds += _timeRoundStarted;
	return timeRoundEnds;
}

/**
* \brief Gets the bomb position. 
*
* \param[in] armed Set to 'true' if want to seek armed bomb position. Set to 'false'
* if want to seek bomb in backpack position. Defaults to 'true'.
**/
Vector World::getBombPosition(bool armed)
{
	Vector vecBomb = Vector(9999, 9999, 9999);
	edict_t *pent = NULL;
	if(armed){
		while (!FNullEnt(pent = FIND_ENTITY_BY_STRING( pent, "classname", "grenade" )))
		{
			if (FStrEq(STRING(pent->v.model) + 9, "c4.mdl"))
			{
				vecBomb = pent->v.origin;
				break;
			}
		}
	}
	else{ //On the floor...(inside backpack)
		while (!FNullEnt(pent = FIND_ENTITY_BY_STRING( pent, "classname", "weaponbox" )))
		{
			if (FStrEq(STRING(pent->v.model) + 9, "backpack.mdl"))
			{
				vecBomb = pent->v.origin;
				break;
			}
		}
	}

	return vecBomb;
}